import ast
import ujson
import traceback
from pathlib import Path
from collections import Counter


def read_file(file: Path = None):
    content = ''
    with open(file, 'r') as f:
        content = f.read()
        try:
            return content.decode(encoding='utf-8', errors='ignore')
        except (UnicodeError, AttributeError):
            return content


def find_duplicate_keys(json_obj, prefix="", duplicate_keys=None):
    '''
    检查JSON对象中是否存在重复的键
    '''
    if duplicate_keys is None:
        duplicate_keys = []

    if isinstance(json_obj, dict):
        key_counts = Counter(json_obj.keys())
        for key, count in key_counts.items():
            if count > 1:
                duplicate_keys.append(f"{prefix}.{key}" if prefix else key)

        for value in json_obj.values():
            if isinstance(value, (dict, list)):
                find_duplicate_keys(value, prefix, duplicate_keys)

    elif isinstance(json_obj, list):
        for item in json_obj:
            if isinstance(item, (dict, list)):
                find_duplicate_keys(item, prefix, duplicate_keys)

    return duplicate_keys

def check_duplicate_keys(json_obj, duplicate_check = False):
    if (duplicate_check):
        duplicate_keys = find_duplicate_keys(json_obj)
        if(duplicate_keys):
            raise(f"存在重复的键：{','.join(duplicate_keys)}")
    return json_obj

def json_in_file(file_path: Path = None, duplicate_check: bool = False, read_file_func: object = read_file):
    json_obj = []
    try:
        content = read_file_func(file_path)
        json_obj = ujson.loads(content)
    except:
        try:
            # 如果文件loads失败，猜想并转换单行为JSON的场景 
            json_obj = list(map(lambda x:ast.literal_eval(x),content.splitlines()))
        except:
            raise Exception(f'{file_path} 文件读取失败:\n' +
                            traceback.format_exc())
    return check_duplicate_keys(json_obj,duplicate_check)
